using System.Diagnostics;
using System.Xml;

namespace Vibstudio.X4NET.Xml.Comparision
{
    internal abstract class OperationDescriptor
    {
        protected readonly ulong _operationID;

        internal OperationDescriptor _nextDescriptor;

        internal OperationDescriptor(ulong opid)
        {
            Debug.Assert(opid > 0);
            _operationID = opid;
        }

        protected abstract string Type { get; }

        internal virtual void WriteTo(XmlWriter xmlWriter)
        {
            xmlWriter.WriteStartElement(XmlDiff.Prefix, "descriptor", XmlDiff.NamespaceUri);
            xmlWriter.WriteAttributeString("opid", _operationID.ToString());
            xmlWriter.WriteAttributeString("type", Type);
            xmlWriter.WriteEndElement();
        }
    }

    internal class OperationDescrMove : OperationDescriptor
    {
        internal OperationDescrMove(ulong opid)
            : base(opid)
        {
        }

        protected override string Type
        {
            get { return "move"; }
        }
    }

    internal class OperationDescrNamespaceChange : OperationDescriptor
    {
        private readonly DiffgramGenerator.NamespaceChange _nsChange;

        internal OperationDescrNamespaceChange(DiffgramGenerator.NamespaceChange nsChange)
            : base(nsChange._opid)
        {
            _nsChange = nsChange;
        }

        protected override string Type
        {
            get { return "namespace change"; }
        }

        internal override void WriteTo(XmlWriter xmlWriter)
        {
            xmlWriter.WriteStartElement(XmlDiff.Prefix, "descriptor", XmlDiff.NamespaceUri);
            xmlWriter.WriteAttributeString("opid", _operationID.ToString());
            xmlWriter.WriteAttributeString("type", Type);

            xmlWriter.WriteAttributeString("prefix", _nsChange._prefix);
            xmlWriter.WriteAttributeString("oldNs", _nsChange._oldNS);
            xmlWriter.WriteAttributeString("newNs", _nsChange._newNS);

            xmlWriter.WriteEndElement();
        }
    }

    internal class OperationDescrPrefixChange : OperationDescriptor
    {
        private DiffgramGenerator.PrefixChange _prefixChange;

        internal OperationDescrPrefixChange(DiffgramGenerator.PrefixChange prefixChange)
            : base(prefixChange._opid)
        {
            _prefixChange = prefixChange;
        }

        protected override string Type
        {
            get { return "prefix change"; }
        }

        internal override void WriteTo(XmlWriter xmlWriter)
        {
            xmlWriter.WriteStartElement(XmlDiff.Prefix, "descriptor", XmlDiff.NamespaceUri);
            xmlWriter.WriteAttributeString("opid", _operationID.ToString());
            xmlWriter.WriteAttributeString("type", Type);

            xmlWriter.WriteAttributeString("ns", _prefixChange._NS);
            xmlWriter.WriteAttributeString("oldPrefix", _prefixChange._oldPrefix);
            xmlWriter.WriteAttributeString("newPrefix", _prefixChange._newPrefix);

            xmlWriter.WriteEndElement();
        }
    }
}